package com.common.sdk.net.connect.http.center.tools;

import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.concurrent.atomic.AtomicBoolean;

import android.content.Context;
import android.os.Environment;
import android.os.StatFs;

import com.android.sohu.sdk.common.toolbox.FileUtils;
import com.android.sohu.sdk.common.toolbox.NetworkUtils;
import com.common.sdk.net.connect.http.DaylilyRequest;

public class CacheUtils {
    private static Context mContext;
    private static File mRootDirectory = null;

    private static final String DEFAULT_DATA_CACHE_DIR = "DATACACHE";
    private static final String DEFAULT_IMAGE_CACHE_DIR = "IMAGE";

    private static final int MB = 1024 * 1024;
    private static final int FREE_SD_SPACE_NEEDED_TO_CACHE = 20 * MB;
    public static final long IMAGE_CACHE_SIZE = 100 * MB;

    private static final String IMAGE_FILE_EXT = ".ich";

    private static final String FILE_EXT = ".dch";

    public static Context getContext() {
        return mContext;
    }

    public static File getRootCacheDir() {
        return mRootDirectory;
    }

    public static File getDataCacheDir() {
        return getCacheDir(DEFAULT_DATA_CACHE_DIR);
    }

    public static File getImageCacheDir() {
        return getCacheDir(DEFAULT_IMAGE_CACHE_DIR);
    }

    public static String getImageCacheName() {
        return DEFAULT_IMAGE_CACHE_DIR;
    }

    private static AtomicBoolean mFileDeleting = new AtomicBoolean(false);

    /**
     * 计算存储目录下的文件大小，
     * 当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定
     * 那么删除40%最近没有被使用的文件
     */
    public static void removeCacheIfNoSpaceLeft() {
        if (mFileDeleting.compareAndSet(false, true)) {
            try {
                File imageDirectory = getImageCacheDir();
                if (imageDirectory == null) {
                    return;
                }
                File[] files = imageDirectory.listFiles();
                if (files == null) {
                    return;
                }

                int dirSize = 0;
                for (int i = 0; i < files.length; i++) {
                    dirSize += files[i].length();
                }

                HttpLog.debug("current image cache size is : " + dirSize);

                if (dirSize > IMAGE_CACHE_SIZE || FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {
                    int removeSize = (int) ((0.4 * dirSize) + 1);
                    // File将按照更新时间从旧到新排序
                    Arrays.sort(files, new FileLastModifySort());

                    int deleteSize = 0;
                    for (int i = 0; i < files.length; i++) {
                        int length = (int) files[i].length();
                        long lastModifyTime = files[i].lastModified();
                        if (files[i].delete()) {
                            deleteSize += length;
                            HttpLog.debug("file removed, lastModify time is:" + lastModifyTime);
                        }
                        if (deleteSize >= removeSize) {

                            dirSize = 0;
                            files = imageDirectory.listFiles();
                            for (int j = 0; j < files.length; j++) {
                                dirSize += files[j].length();
                            }

                            HttpLog.debug("image cache size after delete is : " + dirSize);

                            return;
                        }
                    }
                }
            } finally {
                mFileDeleting.set(false);
            }
        }
    }

    /**
     * 计算sdcard上的剩余空间
     * 
     * @return
     */
    private static int freeSpaceOnSd() {
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
        double sdFreeMB = ((double) stat.getAvailableBlocks() * (double) stat.getBlockSize());
        return (int) sdFreeMB;
    }

    private static File getCacheDir(String path) {
        if (mRootDirectory == null) {
            return null;
        }
        File file = new File(mRootDirectory, path);
        if (file != null) {
            if (!file.exists()) {
                file.mkdirs();
            }
        }
        return file;
    }

    public static void initiateDirectory(Context context) {
        mContext = context;
        mRootDirectory = getAppSdcardCacheDir(context);
        if (mRootDirectory == null) {
            HttpLog.debug("sd card may not exists");
            return;
        }
        if (!mRootDirectory.exists()) {
            mRootDirectory.mkdirs();
        }
    }

    protected static File getAppSdcardCacheDir(Context context) {

        File appCacheDir = null;
        try {
            appCacheDir = context.getExternalFilesDir(null);
        } catch (Exception e) {
            return null;
        }
        if (appCacheDir == null) {
            return null;
        }
        HttpLog.debug("externalFileDirs  is : " + appCacheDir.getAbsolutePath());

        if (!appCacheDir.exists()) {
            if (!appCacheDir.mkdirs()) {
                HttpLog.debug("Unable to create external cache directory");
                return null;
            }
        }
        return appCacheDir;
    }

    private static class FileLastModifySort implements Comparator<File> {

        @Override
        public int compare(File lhs, File rhs) {
            if (lhs.lastModified() > rhs.lastModified()) {
                return 1;
            } else if (lhs.lastModified() == rhs.lastModified()) {
                return 0;
            } else {
                return -1;
            }
        }

    }

    public static boolean isOnline() {
        return NetworkUtils.isOnline(mContext);
    }

    /**
     * Returns a file object for the given cache key.
     */
    public static File getImageFileForKey(String key) {
        File imageDir = getImageCacheDir();
        if (imageDir == null) {
            return null;
        }
        return new File(imageDir, FileUtils.getFilenameForKey(key, IMAGE_FILE_EXT));
    }
}
